package ch.ti.bfh.app.loodel.internal;

import ch.ti.bfh.app.loodel.domain.learningEvent.LearningEvent;
import ch.ti.bfh.app.loodel.domain.learningEvent.LearningEventRepository;
import ch.ti.bfh.app.loodel.domain.member.Member;
import ch.ti.bfh.app.loodel.domain.timeslot.Location;
import ch.ti.bfh.app.loodel.domain.timeslot.TimeSlot;
import ch.ti.bfh.app.loodel.domain.timeslot.TimeSlotRepository;
import ch.ti.bfh.app.loodel.internal.security.InternalUserContext;
import ch.ti.bfh.app.loodel.service.LearningEventInvitationData;
import ch.ti.bfh.app.loodel.service.MemberData;
import ch.ti.bfh.app.loodel.service.SendLearningEventInvitationService;
import ch.ti.bfh.app.loodel.service.create.CreateLearningEventData;
import ch.ti.bfh.app.loodel.service.create.CreateLearningEventService;
import ch.ti.bfh.app.loodel.service.create.CreateTimeSlotData;
import ch.ti.bfh.app.loodel.service.create.ShowTimeSlotLocationData;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.inject.Inject;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Transactional
public class DefaultCreateLearningEventService implements CreateLearningEventService {

    private final LearningEventRepository learningEventRepository;

    private final TimeSlotRepository timeSlotRepository;

    private final InternalUserContext userContext;

    private final SendLearningEventInvitationService sendLearningEventInvitationService;

    @Inject
    public DefaultCreateLearningEventService(LearningEventRepository learningEventRepository, TimeSlotRepository timeSlotRepository, InternalUserContext userContext, SendLearningEventInvitationService sendLearningEventInvitationService) {
        this.learningEventRepository = learningEventRepository;
        this.timeSlotRepository = timeSlotRepository;
        this.userContext = userContext;
        this.sendLearningEventInvitationService = sendLearningEventInvitationService;
    }

    @Override
    public String createNewLearningEvent(CreateLearningEventData createLearningEventData) {
        Member member = userContext.getCurrentMember();
        List<CreateTimeSlotData> createTimeSlotDataList = createLearningEventData.getTimeSlots();
        Set<TimeSlot> timeSlotsForLearningEvent = new HashSet<TimeSlot>(createTimeSlotDataList.size());
        LearningEvent newLearningEvent = new LearningEvent(member, createLearningEventData.getGroupName(), createLearningEventData.getModuleName(), timeSlotsForLearningEvent);
        newLearningEvent.setDescription(createLearningEventData.getComment());
        for (CreateTimeSlotData createTimeSlotData : createTimeSlotDataList) {
            TimeSlot newTimeSlot = new TimeSlot(newLearningEvent, createTimeSlotData.getDateTimeInterval(), new Location(createTimeSlotData.getLocationName(), createTimeSlotData.getStreet(), createTimeSlotData.getPlace()));
            newTimeSlot.setComment(createTimeSlotData.getComment());
            timeSlotsForLearningEvent.add(timeSlotRepository.save(newTimeSlot));
        }
        newLearningEvent = learningEventRepository.save(newLearningEvent);
        return newLearningEvent.getId();
    }

    @Override
    public String createNewLearningEventAndSendInvitation(CreateLearningEventData createLearningEventData, LearningEventInvitationData learningEventInvitationData) {
        final String newLearningEventId = createNewLearningEvent(createLearningEventData);
        this.sendLearningEventInvitationService.sendLearningEventInvitation(newLearningEventId, learningEventInvitationData);
        return newLearningEventId;
    }

    @Override
    public ShowTimeSlotLocationData getTimeSlotLocationData(Long timeSlotId) {
        TimeSlot timeSlot = timeSlotRepository.findOne(timeSlotId);
        return TimeSlotAssembler.createTimeSlotLocationData(timeSlotId, timeSlot.getLocation());
    }

    @Override
    public MemberData getMemberDataForInvitation(String email) {
        return this.sendLearningEventInvitationService.getMemberDataForInvitation(email);
    }

    @Override
    public List<MemberData> findMemberDataForInvitation(String queryTerm) {
        return this.sendLearningEventInvitationService.findMemberDataForInvitation(queryTerm);
    }

    @Override
    public String getInvitationDefaultText(CreateLearningEventData createLearningEventData, String customText) {
        return sendLearningEventInvitationService.getInvitationDefaultText(createLearningEventData, customText);
    }

}
